from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
import json
# 导入自定义序列化器
from books.serialziers import BookSerialzier, HeroSerialzier
from books.models import BookInfo, HeroInfo


class BooksView(View):
    def post(self, request):
        """
            保存图书
        :param request:
        :return:
        """
        # 1、前端传递保存图书的数据 json接受
        json_data = request.body.decode()
        dict_data = json.loads(json_data)
        # 2、验证数据
        ser = BookSerialzier(data=dict_data)
        # is_valid 序列化器提供的验证方法 raise_exception=True 的作用是，验证失败抛出异常
        try:
            ser.is_valid(raise_exception=True)
        except Exception as e:
            print(e)
            return JsonResponse({"error": '数据验证失败'})
        # # errors 获取验证的信息内容，数据验证成功返回空字典{}
        # print(ser.errors)
        # if ser.errors:
        #     # ser.errors有数据，说明验证失败，需要进行返回
        #     return JsonResponse({'errmsg':ser.errors})

        # 3、保存数据
        data = ser.validated_data
        # 调用序列化封装的保存业务逻辑
        ser.save()
        # 4、返回结果
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中

        # # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)

    def get(self, request):
        """
            获取图书
            :param request:
            :return:
        """
        books = BookInfo.objects.all()
        book_list = []
        for book in books:
            book_list.append({
                'id': book.id,
                'btitle': book.btitle,
                'bpub_date': book.bpub_date,
                'bread': book.bread
            })

        # 4、返回结果
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中,在返回多个数据时，需要额外增加一个many=true的参数
        ser = BookSerialzier(books,many=True)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse({'books': ser.data})


class BookView(View):

    def delete(self, request, id):
        """
            删除一本图书
            :param request:
            :param pk: 图书id
            :return:
        """
        try:
            book = BookInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400'}, status=400)

        # 逻辑删除
        book.is_delete = True
        book.save()
        return JsonResponse({})

    def put(self, request, id):
        """
            更新一本图书
            :param request:
            :param pk: 图书id
            :return:
        """
        # 查询更新的图书
        try:
            book = BookInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)
        # 获取更新的字段
        json_data = request.body.decode()
        dict_data = json.loads(json_data)
        # 验证数据
        # 更新业务中，序列化器初始化是除了要传递验证字段外，还要传递要更新的数据对象
        ser = BookSerialzier(book,data = dict_data)
        try:
            ser.is_valid(raise_exception=True)
        except Exception as e:
            print(e)
            return JsonResponse({"error": '数据验证失败'})

        # 更新数据
        # 调用序列化器封装的update方法 save方法通过序列化器初始化是是否传递数据对象来确定调用cerate方法还是update方法，有数据对象调用update方法
        ser.save()
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)

    def get(self, request, id):
        """
            获取一本图书
        :param request:
        :param pk:  图书id
        :return:
        """
        try:
            book = BookInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)

        ser = BookSerialzier(book)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)


class HerosView(View):
    def post(self, request):
        """
            保存英雄
        :param request:
        :return:
        """
        # 1、前端传递保存图书的数据 json接受
        json_data = request.body.decode()
        dict_data = json.loads(json_data)
        hname = dict_data.get('hname')
        hgender = dict_data.get('hgender')
        hcomment = dict_data.get('hcomment')
        # 2、验证数据
        if not hname:
            return JsonResponse({'code': '400'}, status=400)

        # 3、保存数据
        hero = HeroInfo.objects.create(hname = hname)
        # 4、返回结果
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中
        ser = HeroSerialzier(hero)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)


    def get(self, request):
        """
            获取图书
            :param request:
            :return:
        """
        heros = HeroInfo.objects.all()
        hero_list = []
        for hero in heros:
            hero_list.append({
                'id': hero.id,
                'hname': hero.hname,
                'hgender': hero.hgender,
                'hcomment': hero.hcomment
            })

        # 4、返回结果
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中,在返回多个数据时，需要额外增加一个many=true的参数
        ser = HeroSerialzier(heros, many=True)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse({'heros': ser.data})


class HeroView(View):

    def delete(self, request, id):
        """
            删除一个英雄
            :param request:
            :param pk: 英雄id
            :return:
        """
        try:
            hero = HeroInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400'}, status=400)

        # 逻辑删除
        hero.is_delete = True
        hero.save()
        return JsonResponse({})

    def put(self, request, id):
        """
            更新一个英雄
            :param request:
            :param pk: 英雄id
            :return:
        """
        # 查询更新的图书
        try:
            hero = HeroInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)
        # 获取更新的字段
        json_data = request.body.decode()
        dict_data = json.loads(json_data)
        hname = dict_data.get('hname')
        hgender = dict_data.get('hgender')
        hcomment = dict_data.get('hcomment')

        # if btitle:
        #     book.btitle=btitle
        # if bpub_date:
        #     book.bpub_date=bpub_date
        # if bread:
        #     book.bread=bread
        # book.save()
        HeroInfo.objects.filter(id=id).update(**dict_data)
        hero = HeroInfo.objects.get(id=id)

        ser = HeroSerialzier(hero)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)


    def get(self, request, id):
        """
            获取一个英雄
        :param request:
        :param pk:  英雄id
        :return:
        """
        try:
            hero = HeroInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)
        ser = HeroSerialzier(hero)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)
